package com.xyrl.project.common.util;


import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.lang.reflect.Field;
import java.util.Set;


/**
  * @className ValidatorNewUtil
  * @company 星纭融链科技服务有限公司
  * @author 徐恩源
  * @version 1.0
  * @date 2019-12-27 14:02:46
  * @Description 表单校验框架
  */
public class ValidatorUtil {
    public static ValidatorFactory factory = null;
    static {
        factory = Validation.buildDefaultValidatorFactory();
    }

    /**
     * 校验对象
     * @param bean 要校验对象
     * @param groups 验证的组或组列表
     * @return 空字符串或校验错误信息
     */
    public static <T> void validate(T bean, Class<?>... groups) {
        if (ObjectUtils.isEmpty(bean)) {
            throw new IllegalArgumentException("参数校验错误");
        }
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(bean, groups);
        if (!constraintViolations.isEmpty()) {
            ConstraintViolation cons = (ConstraintViolation) constraintViolations.toArray()[0];
            throw new IllegalArgumentException(cons.getMessage());
        }
    }
    /**
     * 验证class单个属性值
     * @param cls  校验对象class
     * @param fields 要校验属性字段
     * @param values 要校验属性字段值
     * @param groups 验证的组或组列表
     * @return 空字符串或校验错误信息
     */
    public static <T> void validateValue(Class<T> cls, String fields, Object values, Class<?>... groups) {
        if (ObjectUtils.isEmpty(fields) || ObjectUtils.isEmpty(values)) {
            throw new IllegalArgumentException("参数校验错误");
        }
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = null;
        constraintViolations = validator.validateValue(cls, fields, values, groups);
        if (!constraintViolations.isEmpty()) {
            ConstraintViolation cons = (ConstraintViolation) constraintViolations.toArray()[0];
            throw new IllegalArgumentException(cons.getMessage());
        }
    }
    /**
     * 验证class多个属性值，
     * @param cls 校验对象class
     * @param fields 要校验属性字段
     * @param values 要校验属性字段值
     * @param groups 验证的组或组列表
     * @return 空字符串或校验错误信息
     */
    public static <T> void validateValue(Class<T> cls, String[] fields, Object[] values, Class<?>... groups) {
        if (ObjectUtils.isEmpty(fields) || ObjectUtils.isEmpty(values)) {
            throw new IllegalArgumentException("参数校验错误");
        }
        for (int i = 0; i < fields.length; i++) {
            validateValue(cls, fields[i], values[i], groups);
        }
    }
    /**
     * 验证bean单个属性
     * @param bean bean对象
     * @param propertyName 属性名
     * @param groups 验证的组或组列表
     * @return 空字符串或校验错误信息
     */
    public static <T> void validateProperty(T bean, String propertyName, Class<?>... groups) {
        if (ObjectUtils.isEmpty(bean) || ObjectUtils.isEmpty(propertyName)) {
            throw new IllegalArgumentException("参数校验错误");
        }
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> consSet = validator.validateProperty(bean, propertyName, groups);
        if (null != consSet && !consSet.isEmpty()) {
            ConstraintViolation cons = (ConstraintViolation) consSet.toArray()[0];
            throw new IllegalArgumentException(cons.getMessage());
        }
    }

    /**
     * 验证bean多个属性
     * @param bean         bean对象
     * @param propertyName 属性名
     * @param groups       验证的组或组列表
     * @return 空字符串或校验错误信息
     */
    public static <T> void validateProperty(T bean, String[] propertyName, Class<?>... groups) {
        for (int i = 0; i < propertyName.length; i++) {
            validateProperty(bean, propertyName[i], groups);
        }
    }
    /**
     * 验证bean全部属性
     * @param bean bean对象
     * @param groups 验证的组或组列表
     * @return 空字符串或校验错误信息
     */
    public static <T> void validateProperty(T bean, Class<?>... groups) {
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = null;
        Field[] fields = bean.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            constraintViolations = validator.validateProperty(bean, fields[i].getName(), groups);
            if (!constraintViolations.isEmpty()) {
                ConstraintViolation cons = (ConstraintViolation) constraintViolations.toArray()[0];
                throw new IllegalArgumentException(cons.getMessage());
            }
        }
    }
}